#include "CEUtilities.h"

#include "CEMouse.h"
#include "CEGUIManager.h"
#include "CEGUIPictureBox.h"
#include "CEGUIScrollBarVertical.h"
#include "CEFontManager.h"
#include "CEGUIDropdownList.h"


CEGUIDropdownList::CEGUIDropdownList(CEGUIElementBase * parent, int myid, string myname , 
				int offsetX, int offsetY, int width, int height, bool enable, bool visible)
				: CEGUIElementBase(parent, myid, myname, offsetX, offsetY, 
				width, height, enable, visible), heightOfLine(20)
{
	m_eType = GUI_DropdownList;

	int id = CEGUIManager::GetSingleton()->GetNextID();
	string name = CEUtil::IntToStr(id);
	m_pPicTitleLeft  = new CEGUIPictureBox(this, id, name, "Texture/GUI-OGRE.tga", true, Color::White, 0, 0, 6, 20);
	m_pPicTitleLeft->SetUVMap(138.f/256, 2.f/256, 144.f/256, 18.f/256);

	id = CEGUIManager::GetSingleton()->GetNextID();
	name = CEUtil::IntToStr(id);
	m_pPicTitleMid	= new CEGUIPictureBox(this, id, name, "Texture/GUI-OGRE.tga", true, Color::White, 0, 0, 15, 20);
	m_pPicTitleMid->SetUVMap(144.f/256, 2.f/256, 159.f/256, 18.f/256);
	
	id = CEGUIManager::GetSingleton()->GetNextID();
	name = CEUtil::IntToStr(id);
	m_pPicTitleRight	= new CEGUIPictureBox(this, id, name, "Texture/GUI-OGRE.tga", true, Color::White, 0, 0, 15, 20);
	m_pPicTitleRight->SetUVMap(159.f/256, 2.f/256, 174.f/256, 18.f/256);

	id = CEGUIManager::GetSingleton()->GetNextID();
	name = CEUtil::IntToStr(id);
	m_pPicBodyUpEdgeLeft = new CEGUIPictureBox(this, id, name, "Texture/GUI-OGRE.tga", true, Color::White, 0, 0, 4, 4);
	m_pPicBodyUpEdgeLeft->SetUVMap(138.f/256, 38.f/256, 142.f/256, 42.f/256);

	id = CEGUIManager::GetSingleton()->GetNextID();
	name = CEUtil::IntToStr(id);
	m_pPicBodyUpEdgeRight = new CEGUIPictureBox(this, id, name, "Texture/GUI-OGRE.tga", true, Color::White, 0, 0, 4, 4);
	m_pPicBodyUpEdgeRight->SetUVMap(162.f/256, 38.f/256, 166.f/256, 42.f/256);

	id = CEGUIManager::GetSingleton()->GetNextID();
	name = CEUtil::IntToStr(id);
	m_pPicBodyMidEdgeLeft = new CEGUIPictureBox(this, id, name, "Texture/GUI-OGRE.tga", true, Color::White, 0, 0, 4, 18);
	m_pPicBodyMidEdgeLeft->SetUVMap(138.f/256, 42.f/256, 142.f/256, 60.f/256);

	id = CEGUIManager::GetSingleton()->GetNextID();
	name = CEUtil::IntToStr(id);
	m_pPicBodyMidEdgeRight = new CEGUIPictureBox(this, id, name, "Texture/GUI-OGRE.tga", true, Color::White, 0, 0, 4, 18);
	m_pPicBodyMidEdgeRight->SetUVMap(162.f/256, 42.f/256, 166.f/256, 60.f/256);

	id = CEGUIManager::GetSingleton()->GetNextID();
	name = CEUtil::IntToStr(id);
	m_pPicBodyBtmLeft = new CEGUIPictureBox(this, id, name, "Texture/GUI-OGRE.tga", true, Color::White, 0, 0, 4, 6);
	m_pPicBodyBtmLeft->SetUVMap(138.f/256, 60.f/256, 142.f/256, 66.f/256);
	
	id = CEGUIManager::GetSingleton()->GetNextID();
	name = CEUtil::IntToStr(id);
	m_pPicBodyBtmCentre = new CEGUIPictureBox(this, id, name, "Texture/GUI-OGRE.tga", true, Color::White, 0, 0, 20, 6);
	m_pPicBodyBtmCentre->SetUVMap(142.f/256, 60.f/256, 162.f/256, 66.f/256);

	id = CEGUIManager::GetSingleton()->GetNextID();
	name = CEUtil::IntToStr(id);
	m_pPicBodyBtmRight = new CEGUIPictureBox(this, id, name, "Texture/GUI-OGRE.tga", true, Color::White, 0, 0, 4, 6);
	m_pPicBodyBtmRight->SetUVMap(162.f/256, 60.f/256, 166.f/256, 66.f/256);

	id = CEGUIManager::GetSingleton()->GetNextID();
	name = CEUtil::IntToStr(id);
	m_pPicBodyCentre = new CEGUIPictureBox(this, id, name, "Texture/GUI-OGRE.tga", true, Color::White, 0, 0, 20, 22);
	m_pPicBodyCentre->SetUVMap(142.f/256, 38.f/256, 162.f/256, 60.f/256);

	id = CEGUIManager::GetSingleton()->GetNextID();
	name = CEUtil::IntToStr(id);
	m_pScrollBarVerti = new CEGUIScrollBarVertical(this, id, name, 0, 0, 6, 200);

	SetSize(width, height);

	m_iChoosenLabelIndex = 0;
	m_bOpenMode = false;


	_bGUIEditPosControled = false;
	_bGUIEditSizeHControled = false;
	_bGUIEditSizeVControled = false;
	_bGUIEditSizeHVControled = false;

}

CEGUIDropdownList::~CEGUIDropdownList()
{
	FinalCleanUp();
}

void CEGUIDropdownList::SetSize(int width, int height)
{
	CEGUIElementBase::SetSize(width, height);

	m_pPicTitleLeft->SetPosition(0,0);
	m_pPicTitleRight->SetPosition(width - m_pPicTitleRight->GetSize().x, 0);
	m_pPicTitleMid->SetPosition(m_pPicTitleLeft->GetSize().x, 0);
	m_pPicTitleMid->SetSize(width - m_pPicTitleLeft->GetSize().x - m_pPicTitleRight->GetSize().x, m_pPicTitleMid->GetSize().y);

	m_pPicBodyUpEdgeLeft->SetPosition(0, m_pPicTitleLeft->GetSize().y);
 	m_pPicBodyUpEdgeRight->SetPosition(width - m_pPicBodyUpEdgeRight->GetSize().x, m_pPicTitleLeft->GetSize().y);

	m_pPicBodyBtmLeft->SetPosition(0, height - m_pPicBodyBtmLeft->GetSize().y);
	m_pPicBodyBtmRight->SetPosition(width - m_pPicBodyBtmRight->GetSize().x, height - m_pPicBodyBtmRight->GetSize().y);
	m_pPicBodyBtmCentre->SetPosition(m_pPicBodyBtmLeft->GetSize().x, height - m_pPicBodyBtmCentre->GetSize().y);
	m_pPicBodyBtmCentre->SetSize(width - m_pPicBodyBtmLeft->GetSize().x - m_pPicBodyBtmRight->GetSize().x, m_pPicBodyBtmCentre->GetSize().y);

	m_pPicBodyMidEdgeLeft->SetPosition(0, m_pPicBodyUpEdgeLeft->GetOffsetFromParent().y + m_pPicBodyUpEdgeLeft->GetSize().y);
	m_pPicBodyMidEdgeLeft->SetSize(m_pPicBodyMidEdgeLeft->GetSize().x, height - m_pPicBodyBtmLeft->GetSize().y - m_pPicBodyMidEdgeLeft->GetOffsetFromParent().y);
	m_pPicBodyMidEdgeRight->SetPosition(width - m_pPicBodyMidEdgeRight->GetSize().x, m_pPicBodyUpEdgeRight->GetOffsetFromParent().y + m_pPicBodyUpEdgeRight->GetSize().y);
	m_pPicBodyMidEdgeRight->SetSize(m_pPicBodyMidEdgeRight->GetSize().x, height - m_pPicBodyBtmRight->GetSize().y - m_pPicBodyMidEdgeRight->GetOffsetFromParent().y);
	
	m_pPicBodyCentre->SetPosition(m_pPicBodyUpEdgeLeft->GetSize().x, m_pPicBodyUpEdgeLeft->GetOffsetFromParent().y);
 	m_pPicBodyCentre->SetSize(width - m_pPicBodyUpEdgeLeft->GetSize().x - m_pPicBodyUpEdgeRight->GetSize().x, height - m_pPicTitleMid->GetSize().y - m_pPicBodyBtmCentre->GetSize().y);
 	m_pPicBodyCentre->SetSize(width - m_pPicBodyUpEdgeLeft->GetSize().x, height - m_pPicTitleMid->GetSize().y - m_pPicBodyBtmCentre->GetSize().y);


	m_pScrollBarVerti->SetPosition(width - m_pScrollBarVerti->GetSize().x - 1, m_pPicTitleRight->GetSize().y);
	m_pScrollBarVerti->SetHeight(height - m_pScrollBarVerti->GetOffsetFromParent().y);
}


HRESULT CEGUIDropdownList::Render()
{
	if(m_bVisible)
	{
		HRESULT r = S_OK;

		_DrawTitle();
		_DrawCurrentLabel();
		
		if (m_bOpenMode)
		{
			_DrawBody();
			_DrawList();
		}

		return r;
	}
	else
		return S_FALSE;
}


void CEGUIDropdownList::_DrawTitle()
{
	m_pPicTitleLeft->Render();
	m_pPicTitleMid->Render();
	m_pPicTitleRight->Render();
}


void CEGUIDropdownList::_DrawBody()
{
	m_pPicBodyUpEdgeLeft->Render();
	m_pPicBodyUpEdgeRight->Render();
	m_pPicBodyMidEdgeLeft->Render();
	m_pPicBodyMidEdgeRight->Render();
	m_pPicBodyCentre->Render();

	m_pPicBodyBtmLeft->Render();
	m_pPicBodyBtmCentre->Render();
	m_pPicBodyBtmRight->Render();

	m_pScrollBarVerti->Render();
}



void CEGUIDropdownList::SetPosition(int offsetXFromParent, int offsetYFromParent)
{
	CEGUIElementBase::SetPosition(offsetXFromParent, offsetYFromParent);
	
	m_pPicTitleLeft->Move(0, 0);
	m_pPicTitleMid->Move(0, 0);
	m_pPicTitleRight->Move(0, 0);

	m_pPicBodyUpEdgeLeft->Move(0, 0);
	m_pPicBodyUpEdgeRight->Move(0, 0);
	m_pPicBodyMidEdgeLeft->Move(0, 0);
	m_pPicBodyMidEdgeRight->Move(0, 0);
	m_pPicBodyCentre->Move(0, 0);

	m_pPicBodyBtmLeft->Move(0, 0);
	m_pPicBodyBtmCentre->Move(0, 0);
	m_pPicBodyBtmRight->Move(0, 0);

	m_pScrollBarVerti->Move(0, 0);

}


void CEGUIDropdownList::Move(int offsetx, int offsety)
{
	CEGUIElementBase::Move(offsetx, offsety);

	m_pPicTitleLeft->Move(0, 0);
	m_pPicTitleMid->Move(0, 0);
	m_pPicTitleRight->Move(0, 0);

	m_pPicBodyUpEdgeLeft->Move(0, 0);
	m_pPicBodyUpEdgeRight->Move(0, 0);
	m_pPicBodyMidEdgeLeft->Move(0, 0);
	m_pPicBodyMidEdgeRight->Move(0, 0);
	m_pPicBodyCentre->Move(0, 0);

	m_pPicBodyBtmLeft->Move(0, 0);
	m_pPicBodyBtmCentre->Move(0, 0);
	m_pPicBodyBtmRight->Move(0, 0);

	m_pScrollBarVerti->Move(0, 0);
}



void CEGUIDropdownList::FinalCleanUp()
{
	SAFE_DELETE(m_pPicTitleLeft);
	SAFE_DELETE(m_pPicTitleMid);
	SAFE_DELETE(m_pPicTitleRight);

	SAFE_DELETE(m_pPicBodyUpEdgeLeft);
	SAFE_DELETE(m_pPicBodyUpEdgeRight);
	SAFE_DELETE(m_pPicBodyMidEdgeLeft);
	SAFE_DELETE(m_pPicBodyMidEdgeRight);
	SAFE_DELETE(m_pPicBodyCentre);

	SAFE_DELETE(m_pPicBodyBtmLeft);
	SAFE_DELETE(m_pPicBodyBtmCentre);
	SAFE_DELETE(m_pPicBodyBtmRight);

	SAFE_DELETE(m_pScrollBarVerti);
}


bool CEGUIDropdownList::AddLabel(string content)
{
	for (size_t i = 0; i < m_List.size(); ++i)
	{
		if (m_List[i] == content)
			return false;
	}

	m_List.push_back(content);

	return true;
}
	

bool CEGUIDropdownList::DeleteLabel(string content)
{
	for (vector<string>::iterator p = m_List.begin(); p != m_List.end(); ++p)
	{
		if ((*p) == content)
		{
			m_List.erase(p);
			return true;
		}
	}
	return false;
}

bool CEGUIDropdownList::DeleteLabel(int index)
{
	if (m_List.empty())
		return false;

	if (index == 0)
	{
		m_List.pop_back();
		return true;
	}

	if (index < 1 || index >= m_List.size())
		return false;

	vector<string>::iterator p = m_List.begin();
	while(--index)	++p;

	m_List.erase(p);	

	return true;
}


bool CEGUIDropdownList::_DrawCurrentLabel()
{
	if (m_iChoosenLabelIndex < 0 || m_iChoosenLabelIndex >= m_List.size() || m_List.size() == 0)
		return false;

	CEFontManager::GetSingleton()->m_pNormalFont->DrawText(m_List[m_iChoosenLabelIndex], Color::White, 
		m_pPicTitleMid->GetPosition().x+10, m_pPicTitleMid->GetPosition().y, 
		m_pPicTitleMid->GetPosition().x + m_pPicTitleMid->GetSize().x, m_pPicTitleMid->GetPosition().y + m_pPicTitleMid->GetSize().y, 
		AF_VMD_LEFT);

	return true;
}


void CEGUIDropdownList::_DrawList()
{
	int maxShowCount = (m_pPicBodyCentre->GetSize().y - 8)/heightOfLine;

	int begin = ((int)m_List.size() - maxShowCount) * m_pScrollBarVerti->GetValue();
	if (begin < 0) begin = 0;

	int left = m_pPicBodyCentre->GetPosition().x + 10;
	int top = m_pPicBodyCentre->GetPosition().y + 4;
	int right = m_pPicBodyCentre->GetPosition().x + m_pPicBodyCentre->GetSize().x - 10;
	int buttom = top + heightOfLine;
	
	for (size_t i = begin; i < m_List.size() && i < begin+maxShowCount; ++i)
	{
		if (m_iChoosenLabelIndex != i)
			CEFontManager::GetSingleton()->m_pSystemFont->DrawText(m_List[i], Color::White, 
			left, top, right, buttom, AF_VMD_LEFT);
		else
			CEFontManager::GetSingleton()->m_pSystemFont->DrawText(m_List[i], Color::Red, 
			left, top, right, buttom, AF_VMD_LEFT);

		top = buttom;
		buttom = top + heightOfLine;
	}
}


HRESULT CEGUIDropdownList::Update(float deltaTime)
{
	if (Mouse::GetSingleton()->IsMouseKeyDown(0, true))
	{
		if (CEUtil::DotInRect(Mouse::GetSingleton()->GetPos().x, Mouse::GetSingleton()->GetPos().y,
			m_pPicTitleRight->GetPosition().x + 1, m_pPicTitleRight->GetPosition().y + 1,
			m_pPicTitleRight->GetSize().x - 2, m_pPicTitleRight->GetSize().y - 2))
		{
			m_bOpenMode = !m_bOpenMode;
		}
		else if (m_bOpenMode)
		{
			int left = m_pPicBodyCentre->GetPosition().x + 10;
			int top = m_pPicBodyCentre->GetPosition().y + 4;
			int width = m_pPicBodyCentre->GetSize().x - 20;

			int maxShowCount = (m_pPicBodyCentre->GetSize().y - 8)/heightOfLine;
			int firstindex = ((int)m_List.size() - maxShowCount)* m_pScrollBarVerti->GetValue();
			if (firstindex < 0) firstindex = 0;
			int showCount = (((int)m_List.size()-firstindex) < maxShowCount) ? (int)m_List.size()-firstindex : maxShowCount;
			int height = showCount * heightOfLine;
			if (CEUtil::DotInRect(Mouse::GetSingleton()->GetPos().x, Mouse::GetSingleton()->GetPos().y,
				left, top, width, height))
			{
				m_iChoosenLabelIndex = (Mouse::GetSingleton()->GetPos().y - top) / heightOfLine + firstindex;
				m_bOpenMode = !m_bOpenMode;
			}	
		}

	}

	int scroll = Mouse::GetSingleton()->GetScroll();
	if (m_bOpenMode && scroll)
	{
		if (CEUtil::DotInRect(Mouse::GetSingleton()->GetPos().x, Mouse::GetSingleton()->GetPos().y,
			m_pPicBodyCentre->GetPosition().x, m_pPicBodyCentre->GetPosition().y,
			m_pPicBodyCentre->GetSize().x, m_pPicBodyCentre->GetSize().y))
		{
			scroll /= 120;
			float deltValue = -1.f/m_List.size() * scroll;
			m_pScrollBarVerti->SetValue(deltValue + m_pScrollBarVerti->GetValue());
		}
	}

	if (m_bOpenMode)
		m_pScrollBarVerti->Update(deltaTime);


	return S_OK;
}


void CEGUIDropdownList::SaveInScrips(ofstream &fout, int level)
{
	string blank = "";
	int temp = level;
	while (temp--) blank += "\t\t";

	fout << endl;
	fout << blank << "<element_begin>" << endl;
	fout << blank << "\t" << "<DropdownList>" << endl;

	if (m_strName != CEUtil::IntToStr(m_nID))
		fout << blank << "\t\t" << "<name>" << "\t" << m_strName << endl;
	fout << blank << "\t\t" << "<size>" << "\t" << m_Size.x << "\t" << m_Size.y << endl;
	fout << blank << "\t\t" << "<offset>" << "\t" << m_OffsetFromParent.x << "\t" << m_OffsetFromParent.y << endl;
	fout << blank << "\t\t" << "<visible>" << "\t" << m_bVisible << endl;
	fout << blank << "\t\t" << "<enable>" << "\t" << m_bEnable << endl;
	fout << blank << "\t\t" << "<level>" << "\t" << m_iShowLevel << endl;

	for (size_t i = 0; i < m_List.size(); ++i)
	{
		fout << blank << "\t\t" << "<text>" << "\t" << m_List[i] << endl;
	}

	fout << blank << "<element_end>" << endl;
}



void CEGUIDropdownList::SaveInScrips(CEGUIDropdownList* ddl, ofstream &fout, int level)
{
	if (ddl)
	{
		ddl->SaveInScrips(fout, level);
	}
	else
	{
		string blank = "";
		int temp = level;
		while (temp--) blank += "\t\t";
		fout << endl;
		fout << blank << "<element_begin>" << endl;
		fout << blank << "\t" << "<DropdownList>" << endl;
		fout << blank << "\t\t" << "<NULL>" << endl;
		fout << blank << "<element_end>" << endl;
	}
}

bool CEGUIDropdownList::SetChoosenLabelIndex(int index)
{
	if (index < 0 || index > m_List.size())
		return false;

	m_iChoosenLabelIndex = index;

	//int maxShowCount = (m_pPicBodyCentre->GetSize().y - 8)/heightOfLine;
	//if ((m_List.size() - maxShowCount) < 0)
	//{
	//	value = 0;
	//}
	//else
	//{
	//	value = ((float)index)/(m_List.size() - maxShowCount)
	//}
	//int showcount = ((m_List.size() - maxShowCount) < 0) ? 0 : m_List.size() - maxShowCount;
	//if (showcount)
	//value = indexshowcount
	//m_pScrollBarVerti->SetValue( index -  );

	return true;
}